#include <assert.h>

#include "interrupt.h"
#include "lock.h"
#include "list.h"
#include "ULT.h"
#include "linkedlist.h"

void Lock_Init(Lock *l)
{
	interruptsOff();
	l->lockStatus = FREE;
	l->list = list_init();
        l->init = 1;
	interruptsOn();
}


void Lock_Acquire(Lock *l)
{
	volatile int run_first = 1;
 	interruptsOff();

	if (l->lockStatus == FREE) 
	{
		l->lockStatus = NOT_FREE;
	} 
	
	else 
	{
                //assert(runThread()->status == RUNNING);
		getcontext(runThread()->context);

		if (run_first) 
		{
                        
			run_first = 0;
                        runThread()->status = WAITING;
			append(l->list, runThread());
                        interruptsOn();
			ULT_Yield(ULT_ANY);
		}
		

	}
	 
	interruptsOn();

}



void Lock_Release(Lock *l)
{
	interruptsOff();

	
	if (l->list->size == 0) 
	{
	
		l->lockStatus = FREE;
	} 
	else 
	{
		/* pop one tcb from this lock's waiting queue to global ready
		queue */
		ThrdCtlBlk *temp = pop(l->list);
                temp->status = RUNNING;		
		appendRunning(temp);
	}
	
	interruptsOn();
}



int Lock_Destroy(Lock *l)
{
	interruptsOff();
	if (l->lockStatus == NOT_FREE) 
	{
		interruptsOn();
		return -1;
	}
	if (! l->list->size == 0) 
	{
		interruptsOn();
		return -1;
	}
        freeList(l->list,1);
	interruptsOn();
	return 0;
}






